package it.unibo.contact.convoyCruiseControlSystem;

import it.unibo.contact.platformuv.RunTimeKb;
import it.unibo.convoycruisecontrol.boatsubsystem.AbstractCommandBoat;
import it.unibo.convoycruisecontrol.boatsubsystem.DashboardManager;
import it.unibo.convoycruisecontrol.boatsubsystem.IBoatFactory;
import it.unibo.convoycruisecontrol.boatsubsystem.IDashboard;
import it.unibo.convoycruisecontrol.boatsubsystem.SendingNavigationInfo;
import it.unibo.convoycruisecontrol.boatsubsystem.SensingBoatStatus;
import it.unibo.convoycruisecontrol.chiefboatsubsystem.ControlPanel;
import it.unibo.convoycruisecontrol.chiefboatsubsystem.DistanceSupervisor;
import it.unibo.convoycruisecontrol.chiefboatsubsystem.IFlagDisplay;
import it.unibo.convoycruisecontrol.chiefboatsubsystem.IFlagDisplayFactory;
import it.unibo.convoycruisecontrol.chiefboatsubsystem.MapManager;
import it.unibo.convoycruisecontrol.chiefboatsubsystem.StatusSupervisor;
import it.unibo.convoycruisecontrol.chiefboatsubsystem.TimingSupervisor;
import it.unibo.java.location.JavaLocationDeviceFactory;
import it.unibo.location.ILocationDeviceFactory;
import it.unibo.location.LocationDevice;
import it.unibo.mycruise.boat.BoatFactory;
import it.unibo.mycruise.boat.Dashboard;
import it.unibo.mycruise.boat.presentation.swing.DashboardFrame;
import it.unibo.mycruise.boat.presentation.swing.DashboardView;
import it.unibo.mycruise.chief.FlagDisplayFactory;
import it.unibo.mycruise.chief.presentation.swing.ChiefFrame;
import it.unibo.mycruise.chief.presentation.swing.ControlPanelController;
import it.unibo.mycruise.chief.presentation.swing.ControlPanelView;
import it.unibo.util.InformationConverter;
import it.unibo.util.PrologInformationConverter;

public class ConvoyCruiseControlBOAT4System extends ConvoyCruiseControlSystemMain 
{
	static int N = 1;	//TODO Occhio ai subject singleton
	static int R = 5;
	static int a = 3;
	static int DT = 3000;

	LocationDevice locDev;

	//Boats
	IBoatFactory boatFactory = new BoatFactory();
	ILocationDeviceFactory locationDeviceFactory = new JavaLocationDeviceFactory();
	
	InformationConverter informationConverter = new PrologInformationConverter();
	
	AbstractCommandBoat[] boats;
	DashboardManager[] dashManagers;
	SendingNavigationInfo[] sendingNavInfo;
	SensingBoatStatus[] sensingBoatsStatus;
	DashboardFrame[] dashFrames;

	public static void main(String[] args)
	{
		ConvoyCruiseControlBOAT4System system = new ConvoyCruiseControlBOAT4System();
		system.doJob();
	}
	
//	@Override
//	protected void configureSystem() 
//	{
//		RunTimeKb.init(view);
//		//Protocols for application messages
//			RunTimeKb.addSubject("TCP", "space","coreCmd", "192.168.1.100",8050);	
//			RunTimeKb.addSubject("TCP", "space","outCmd", "192.168.1.100" ,8050);	
//			RunTimeKb.addSubject("TCP" , "statusSupervisor" , "enabled","192.168.1.100",8060 );   	
//			RunTimeKb.addSubject("TCP" , "mapManager" , "navigationInfo","192.168.1.100",8060 );   	
//			RunTimeKb.addSubject("TCP" , "distanceSupervisor" , "navigationInfo","192.168.1.100",8060 );   	
//			RunTimeKb.addSubject("TCP" , "startSupervisor" , "navigationInfo","192.168.1.100",8060 );   	
//			RunTimeKb.addSubject("TCP" , "timingSupervisor" , "navigationInfo","192.168.1.100",8060 );   	
//			RunTimeKb.addSubject("TCP" , "commandBoat" , "start","192.168.1.107",8070 );   	
//			RunTimeKb.addSubject("TCP" , "commandBoat" , "stop","192.168.1.107",8070 );   	
//		//Application messages
//			RunTimeKb.addInputConnMsg( "coreCmd", true); //system request
//		  		RunTimeKb.addInputConnMsg( "enabled", true);
//		  		RunTimeKb.addInputConnMsg( "navigationInfo", true);
//		  		RunTimeKb.addInputConnMsg( "start", true);
//		  		RunTimeKb.addInputConnMsg( "stop", true);
//	}
	
	@Override
	protected void start() 
	{
		for(int i = 0; i < N; i++)
		{
			boats[i].start();
			dashManagers[i].start();
			sendingNavInfo[i].start();
		}
	}

	
	@Override
	protected void configureSubjects() 
	{
		locDev = locationDeviceFactory.createBestDevice();
		initBoatSubjects();
	}

	private void initBoatSubjects()
	{
		try
		{
			boats = new AbstractCommandBoat[N];
			dashManagers = new DashboardManager[N];
			sendingNavInfo = new SendingNavigationInfo[N];
			sensingBoatsStatus = new SensingBoatStatus[N];
			dashFrames = new DashboardFrame[N];

			for(int i = 0; i < N; i++)
			{
				// init components
				boats[i] = boatFactory.createBoat(locDev, 3);
				boats[i].setName("boat"+3);
				boats[i].setEnv(null);
				boats[i].initInputSupports();

				IDashboard dash = boatFactory.createDashboard();
				dashManagers[i] = new DashboardManager(dash, boats[i].getNavigationInfo(), locDev, 3000, informationConverter);
				dashManagers[i].setName("dashboardManager"+3);
				dashManagers[i].setEnv(null);
				dashManagers[i].initInputSupports();

				sendingNavInfo[i] = new SendingNavigationInfo(DT, boats[i].getNavigationInfo(), informationConverter);
				sendingNavInfo[i].setName("sendingNavigationInfo");
				sendingNavInfo[i].setEnv(null);
				sendingNavInfo[i].initInputSupports();

				sensingBoatsStatus[i] = new SensingBoatStatus(informationConverter);
				sensingBoatsStatus[i].setName("sensingBoatStatus");
				sensingBoatsStatus[i].setEnv(null);
				sensingBoatsStatus[i].initInputSupports();

				boats[i].getStatusBoat().addBoatStatusListener(sensingBoatsStatus[i]);

				// init GUI
				DashboardView dashView = new DashboardView((Dashboard) dash);
				dashFrames[i] = new DashboardFrame(dashView);
			}
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
	}
}

